
module cachemem_dp
    #
    (
        parameter datawidth=64,
        cache_depth=2048,
        cswidth=datawidth/8,
        addr_wid =$clog2(cache_depth),
        addr_lsb=$clog2(cswidth)
    )
    (
        input [addr_wid-1:0]addr_A,
        input [addr_wid-1:0]addr_B,
        input [datawidth-1:0]di_A,
        input [datawidth-1:0]di_B,
        input we_A,
        input we_B,
        input [cswidth-1:0]bsel_A,
        input [cswidth-1:0]bsel_B,
        output [datawidth-1:0]dato_A,
        output [datawidth-1:0]dato_B,
        input clk_A,
        input clk_B
    );
    
    genvar i;
    generate 
        for(i=0;i<cswidth;i=i+1) 
        begin : cacheblk
            cachemem8_dp #(.memdepth(cache_depth)) 
            cacheunit(
                .addr_A(addr_A),
                .addr_B(addr_B),
                .di_A(di_A[7+8*i:0+8*i]),
                .di_B(di_B[7+8*i:0+8*i]),
                .we_A(we_A&bsel_A[i]),
                .we_B(we_B&bsel_B[i]),
                .dato_A(dato_A[7+8*i:0+8*i]),
                .dato_B(dato_B[7+8*i:0+8*i]),
                .clk_A(clk_A),
                .clk_B(clk_B)
            );
        end
    endgenerate
    endmodule
    
    module cachemem8_dp
    #(
        parameter memdepth = 1024,
        memaddr=$clog2(memdepth)
    )
    (
        input [memaddr-1:0]addr_A,
        input [memaddr-1:0]addr_B,
        input [7:0]di_A,
        input [7:0]di_B,
        input we_A,
        input we_B,
        output reg [7:0]dato_A,
        output reg [7:0]dato_B,
        input clk_A,
        input clk_B
     );
    reg [7:0]memcell[memdepth-1:0];
    //begin //: GENERIC_SSRAM
    always @(posedge clk_A)
    begin
        dato_A<=memcell[addr_A];
        if(we_A)memcell[addr_A]<=di_A;
    end
    always @(posedge clk_B)
    begin
        dato_B<=memcell[addr_B];
        if(we_B)memcell[addr_B]<=di_B;
    end
        
    endmodule
    